@tool
@icon("../icons/transition.svg")
class_name Transition
extends Node

#region 属性
@export var active:bool = true
#endregion
#region 字段
@export_node_path("State") var to:NodePath:
	set(value):
		to = value
		update_configuration_warnings()
@export var event:StringName = "":
	set(value):
		event = value
		update_configuration_warnings()
@export var guard:Guard:
	set(value):
		guard = value
		update_configuration_warnings()
var delay_seconds:float = 0.0:
	get:
		if delay_in_seconds.is_valid_float():
			return float(delay_in_seconds)
		return 0.0
var delay_in_seconds:String = "0.0":
	set(value):
		delay_in_seconds = value
		update_configuration_warnings()

var has_event:bool:
	get:
		return event != null and event.length() > 0
#endregion
#region 信号
## 该信号会在转换时触发，对于延迟转换，直到实际转换发生时才触发，总会在State退出前触发
signal taken()
#endregion

#region 基类方法
#endregion
#region 公共方法
func evaluate_guard() -> bool:
	if not active:
		return false
	if guard == null:
		return true
	var parent_state = get_parent()
	if parent_state == null or not parent_state is State:
		push_error("Transition必须是State类型节点的子节点")
		return false
	var to_state:State = resolve_target()
	if not to_state or to_state is not State:
		push_error("目标节点必须有效")
		return false
	return guard.is_satisfied(self,parent_state) and to_state.get_state_status() == GameEnum.StateStatus.Ready
func evaluate_delay() -> float:
	if delay_in_seconds.is_valid_float():
		return float(delay_in_seconds)
	var parent_state = get_parent()
	if parent_state == null or parent_state is not State:
		push_error("Transition必须是State类型的子节点")
		return 0
	var result = ExpressionUtil.evaluate_expression("delay of " + DebugUtil.path_of(self),parent_state.chart,delay_in_seconds,0.0)
	if typeof(result) != TYPE_FLOAT:
		push_error("表达式 {0} 结果不是一个浮点数".format([delay_in_seconds]))
		return 0.0
	return result
func resolve_target() -> State:
	if to == null or to.is_empty():
		return null
	var result = get_node_or_null(to)
	if result is State:
		return result
	return null
#endregion
#region 私有方法
#endregion
#region 生命周期函数
func _get_configuration_warnings() -> PackedStringArray:
	var warning:Array = []
	if get_child_count() > 0:
		warning.append("Transition节点不能有子节点")
	if to == null or to.is_empty():
		warning.append("至少需要一个目标状态")
	if resolve_target() == null:
		warning.append("目标状态找不到")
	elif resolve_target() == get_parent():
		warning.append("目标状态不能是当前状态")
	elif get_parent() is not State:
		warning.append("Transition必须是State类型节点的子节点")
	return warning
func _get_property_list() -> Array[Dictionary]:
	var properties:Array[Dictionary] = []
	properties.append({
		"name" : "delay_in_seconds",
		"type" : TYPE_STRING,
		"usage" : PROPERTY_USAGE_DEFAULT,
		"hint" : PROPERTY_HINT_EXPRESSION,
	})
	properties.append({
		"name" : "delay_seconds",
		"type" : TYPE_FLOAT,
		"usage" : PROPERTY_USAGE_NONE,
	})
	return properties
#endregion
